package com.kl.drs.controller;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.http.client.ClientProtocolException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kl.drs.action.BankButtjointAction;
import com.kl.drs.action.RecordingAction;
import com.kl.drs.bean.bo.BankRequestBO;
import com.kl.drs.bean.bo.CCBLCContBO;
import com.kl.drs.bean.bo.TaskInfoBO;
import com.kl.drs.util.ConfigsUtil;
import com.kl.drs.util.DateFormatUtil;
import com.kl.drs.util.DateUtils;
import com.kl.drs.util.Log4jUtils;
import com.kl.drs.util.MD5FileUtil;



@Controller
public class RecordingController {
	//数据解析
	@Autowired
    private RecordingAction recordingAction;
	@Autowired
	private BankButtjointAction bankButtjointAction;
	
	@RequestMapping(value="/enterTaskView",method = RequestMethod.GET)
    public String enterTaskView() {
        //跳转到 templates 目录下的 uploadimg.html
        return "enterTaskView";
    }
	@RequestMapping(value="/kl-drs/drTaskUpload",method = RequestMethod.POST)
    @ResponseBody
    public String uploadRecordingInfo(HttpServletRequest request, Model model) throws Exception{
    	TaskInfoBO taskInfoBO = pareseRequest(request);
    	System.out.println(taskInfoBO);
    	Map resultMap = recordingAction.uploadRecordingInfo(taskInfoBO);
    	if(resultMap.get("message")!=null && !"".equals(resultMap.get("message"))){
    		return (String)resultMap.get("message");
    	}
		return "upload success!";
    }    

	private TaskInfoBO pareseRequest(HttpServletRequest request)
			throws IOException {
		String dateStr = DateUtils.formatDate("yyyyMMdd");
		// 请求消息实体的总长度(请求消息中除消息头之外的数据长度)
		int totalbytes = request.getContentLength();
		// 请求消息类型
		String contentType = request.getContentType();
		// 在消息头类型中找到分界符的定义
		int pos = contentType.indexOf("boundary=");

		String boundary = ""; // 分界符字符串
		String lastboundary = ""; // 结束分界符字符串
		if (pos != -1) {
			pos += "boundary=".length();
			boundary = "--" + contentType.substring(pos); // 解析出分界符
			lastboundary = boundary + "--"; // 得到结束分界符
		}
		
		
		byte[] b = new byte[totalbytes];
		byte[] dataOrigin = new byte[totalbytes];
		DataInputStream in = new DataInputStream(request.getInputStream());
		in.readFully(dataOrigin); // 根据长度，将消息实体的内容读入字节数组dataOrigin中
		in.close(); // 关闭数据流
		String reqcontent = new String(dataOrigin); // 从字节数组中得到表示实体的字符串
		// 从字符串中得到输出缓冲流
		BufferedReader reqbuf = new BufferedReader(new StringReader(reqcontent));
		File f; // 上传文件储存在服务器上
		int fileSize = 0; // 文件长度

		final int NONE = 0; // 状态码，表示没有特殊操作

		final int DATAHEADER = 1; // 表示下一行要读到报头信息

		final int FILEDATA = 2; // 表示下面要读的是上传文件和二进制数据

		final int FIELDDATA = 3; // 表示下面要读到表单域的文本值
        int state = NONE; // 起始状态为NONE
        String fieldname = ""; // 表单域的名称
        String fieldvalue = ""; // 表单域的值
        String fileFormName = ""; // 上传的文件再表单中的名称
        String fileRealName = ""; // 上传文件的真实名字
        String filePath = "";//文件路径
        String videoType = "";//文件类型
        // 容纳表单域的名称/值的哈希表
        Map<String, String> formfieldsTable = new HashMap<String, String>();
        // 容纳文件域的名称/文件名的哈希表
        Map<String, String> filenameTable = new HashMap<String, String>();
        int pos2;
        
		// 设置循环标志
		boolean flag = true;
		while (flag == true) {
			String s = reqbuf.readLine();
			if (s == lastboundary || s == null)
				break;
			switch (state) {
			case NONE:
				if (s.startsWith(boundary)) {
					// 如果读到分界符，则表示下一行一个头信息
					state = DATAHEADER;
				}
				break;
			case DATAHEADER:
				pos = s.indexOf("filename=");
				// 先判断出这是一个文本表单域的头信息，还是一个上传文件的头信息
				if (pos == -1) {
					// 如果是文本表单域的头信息，解析出表单域的名称
					pos = s.indexOf("name=");
					pos += "name=".length() + 1; // 1表示后面的"的占位
					s = s.substring(pos);
					int l = s.length();
					s = s.substring(0, l - 1); // 应该是"
					fieldname = s; // 表单域的名称放入fieldname
					state = FIELDDATA; // 设置状态码，准备读取表单域的值
				} else {
					// 如果是文件数据的头，先存储这一行，用于在字节数组中定位
					String temp = s;
					// 先解析出文件名
					pos = s.indexOf("name=");
					pos += "name=".length() + 1; // 1表示后面的"的占位
					pos2 = s.indexOf("filename=");
					String s1 = s.substring(pos, pos2 - 3); // 3表示";加上一个空格
					fileFormName = s1;
					pos2 += "filename=".length() + 1; // 1表示后面的"的占位
					s = s.substring(pos2);
					int l = s.length();
					s = s.substring(0, l - 1);
					pos2 = s.lastIndexOf("\\");
					s = s.substring(pos2 + 1);
					fileRealName = s;
					if (fileRealName.length() != 0) { // 确定有文件被上传
						// 下面这一部分从字节数组中取出文件的数据
						b = dataOrigin; // 复制原始数据以便提取文件
						pos = byteIndexOf(b, temp, 0); // 定位行
						// 定位下一行，2 表示一个回车和一个换行占两个字节
						b = subBytes(b, pos + temp.getBytes().length + 2,
						b.length);
						// 再读一行信息，是这一部分数据的Content-type
						s = reqbuf.readLine();
						// 设置文件输入流，准备写文件
						String rootPath = ConfigsUtil.getProperty("truePath");
						filePath = dateStr+File.separator;
						f = new File(rootPath + filePath + fileRealName);
						if(!f.getParentFile().exists()){
							f.getParentFile().mkdirs();
						}
				    	//获取文件类型
				    	videoType=fileRealName.substring(fileRealName.indexOf(".")+1, fileRealName.length());
						DataOutputStream fileout = new DataOutputStream(new FileOutputStream(f));
						// 字节数组再往下一行，4表示两回车换行占4个字节，本行的回车换行2个字节，Content-type的下
						// 一行是回车换行表示的空行，占2个字节
						// 得到文件数据的起始位置
						b = subBytes(b, s.getBytes().length + 4, b.length);
						pos = byteIndexOf(b, boundary, 0); // 定位文件数据的结尾
						b = subBytes(b, 0, pos - 1); // 取得文件数据
						fileout.write(b, 0, b.length - 1); // 将文件数据存盘
						fileout.close();
						fileSize = b.length - 1; // 文件长度存入fileSize
						filenameTable.put(fileFormName, fileRealName);
						state = FILEDATA;
					}
				}
				break;
			case FIELDDATA:
				// 读取表单域的值
				s = reqbuf.readLine();
				fieldvalue = s; // 存入fieldvalue
				formfieldsTable.put(fieldname, fieldvalue);
				state = NONE;
				break;
			case FILEDATA:
				// 如果是文件数据不进行分析，直接读过去
				while ((!s.startsWith(boundary))&& (!s.startsWith(lastboundary))) {
					s = reqbuf.readLine();
					if (s.startsWith(boundary)) {
						state = DATAHEADER;
					} else {
						break;
					}
				}
				break;
			}
		}
		TaskInfoBO taskInfoBO = fillRecording(formfieldsTable);
		if(filePath!=null && !"".equals(filePath)){
			taskInfoBO.setVUrl(filePath);
		}
		if(videoType!=null && !"".equals(videoType)){
			taskInfoBO.setVideoType(videoType);
		}
		if(fileRealName!=null && !"".equals(fileRealName)){
			taskInfoBO.setVideoName(fileRealName);	
		}
		return taskInfoBO;
	}
    private TaskInfoBO fillRecording(Map request){
    	String businessNo = (String)request.get("businessNo");
    	String taskSource = (String)request.get("taskSource");
    	String counterId = (String)request.get("counterId");
    	String counterName = (String)request.get("counterName");
    	String counterPhone = (String)request.get("counterPhone");
    	String bankCode = (String)request.get("bankCode");
    	String subBankCode = (String)request.get("subBankCode");
    	String nodeBankCode = (String)request.get("nodeBankCode");
    	String subInsurerCode = (String)request.get("subInsurerCode");
    	String productName = (String)request.get("productName");
    	String productCode = (String)request.get("productCode");
    	String customerName = (String)request.get("customerName");
    	String customerCardType = (String)request.get("customerCardType");
    	String customerCardNo = (String)request.get("customerCardNo");
    	String customerBirthday = (String)request.get("customerBirthday");
    	String businessSerialNo = (String)request.get("businessSerialNo");
    	String insurerCode = (String)request.get("insurerCode");
    	String vUrl = (String)request.get("vUrl");
    	String videoType = (String)request.get("videoType");
    	String videoName = (String)request.get("videoName");
    	String batchNo = (String)request.get("batchNo");
    	String paymentTerm = (String)request.get("paymentTerm");
    	TaskInfoBO taskInfoBO = new TaskInfoBO();
    	taskInfoBO.setBusinessNo(businessNo);
    	if(taskSource != null && !"".equals(taskSource)){
    		taskInfoBO.setTaskSource(Integer.parseInt(taskSource));
    	}else{
    		taskInfoBO.setTaskSource(2);
    	}
    	
    	taskInfoBO.setCounterId(counterId);
    	taskInfoBO.setCounterName(counterName);
    	taskInfoBO.setCounterPhone(counterPhone);
    	taskInfoBO.setBankCode(bankCode);
    	taskInfoBO.setSubBankCode(subBankCode);
    	taskInfoBO.setNodeBankCode(nodeBankCode);
    	taskInfoBO.setSubInsurerCode(subInsurerCode);
    	taskInfoBO.setProductCode(productCode);
    	taskInfoBO.setProductName(productName);
    	taskInfoBO.setCustomerName(customerName);
    	/*身份证号码*/
    	taskInfoBO.setCustomerCardNo(customerCardNo);
    	/*身份证类型*/
    	if(customerCardType != null && !"".equals(customerCardType)){
    		taskInfoBO.setCustomerCardType(Integer.parseInt(customerCardType));
    	}
    	/*生日*/
    	if(customerBirthday != null && !"".equals(customerBirthday)){
    		/*进行客户生日的截取*/
    		String customerCardNoStr=taskInfoBO.getCustomerCardNo();
    		String customerBirthdayNew=customerCardNoStr.substring(6, 14);
    		StringBuilder sb=new StringBuilder(customerBirthdayNew);
    		sb.insert(4, "-");
    		sb.insert(7, "-");
    		customerBirthdayNew=sb.toString();
    		taskInfoBO.setCustomerBirthday(customerBirthdayNew);
    		
    	}else{
    		taskInfoBO.setCustomerBirthday(customerBirthday);
    		
    	}
    	taskInfoBO.setBusinessSerialNo(businessSerialNo);
    	taskInfoBO.setInsurerCode(insurerCode);
    	taskInfoBO.setBatchNo(batchNo);
    	if(paymentTerm != null && !"".equals(paymentTerm)){
    		taskInfoBO.setPaymentTerm(Integer.parseInt(paymentTerm));
    	}else{
    		taskInfoBO.setPaymentTerm(4);
    	}
    	taskInfoBO.setVUrl(vUrl);
    	taskInfoBO.setVideoName(videoName);
    	taskInfoBO.setVideoType(videoType);
    	//获取文件路径
    	
    	return taskInfoBO;
    }
	
	 private static int byteIndexOf(byte[] b, String s, int start) {

	        return byteIndexOf(b, s.getBytes(), start);

	}
	  private static int byteIndexOf(byte[] b, byte[] s, int start) {

	        int i;

	        if (s.length == 0) {

	        return 0;

	        }

	        int max = b.length - s.length;

	        if (max < 0) {

	        return -1;

	        }

	        if (start > max) {

	        return -1;

	        }

	        if (start < 0) {

	        start = 0;

	        }

	        // 在b中找到s的第一个元素

	        search: for (i = start; i <= max; i++) {

	        if (b[i] == s[0]) {

	        // 找到了s中的第一个元素后，比较剩余的部分是否相等

	        int k = 1;

	        while (k < s.length) {

	        if (b[k + i] != s[k]) {

	        continue search;

	        }

	        k++;

	        }

	        return i;

	        }

	        }

	        return -1;

	        }
	  private static byte[] subBytes(byte[] b, int from, int end) {

	        byte[] result = new byte[end - from];

	        System.arraycopy(b, from, result, 0, end - from);

	        return result;

	        }

	        

	        private static String subBytesString(byte[] b, int from, int end) {

	        return new String(subBytes(b, from, end));

	        }  
      //建行请求前置机(建行)
    	@RequestMapping(value ="/ccb", method = RequestMethod.POST, consumes = {"application/xml;charset=GBK"})
    	@ResponseBody
    	public String requestCCB(@RequestBody BankRequestBO bankRequestBO) throws ClientProtocolException, IOException, ParseException{
    		 JSONObject jsonObject =  JSONObject.fromObject(bankRequestBO);
    		Log4jUtils.debugJson("requestCCB", "--------请求到数据--------"+JSONObject.fromObject(bankRequestBO));
    		//获取LCConto,解析LCCont的数据信息
    		String strLCCont=jsonObject.getString("LCCont");
    		//Log4jUtils.logDebug("------------将json转换成对对象------------------------");
    		JSONObject jsonLCCont = JSONObject.fromObject(strLCCont);
    		CCBLCContBO ccbLCContBO = (CCBLCContBO) JSONObject.toBean(jsonLCCont, CCBLCContBO.class);
    		Map resultMap = bankButtjointAction.bankButtjoint(ccbLCContBO);
    		return resultMap.get("resultXML").toString();
    	}
    	@RequestMapping(value = "/ping")
    	@ResponseBody
    	public String test(){
    		return "pong";
    	}
     }    
    


